package cn.hiapi.shopkeeper.service.activity;

import cn.hiapi.basic.ResUtils;
import cn.hiapi.basic.entity.BasicEntity;
import cn.hiapi.basic.exception.BasicException;
import cn.hiapi.basic.jpa.pageable.QueryWrapper;
import cn.hiapi.basic.redis.service.RedisService;
import cn.hiapi.basic.token.Token;
import cn.hiapi.interfaces.DispatchContext;
import cn.hiapi.shop.service.product.ProductNumService;
import cn.hiapi.shopkeeper.consts.AppConst;
import cn.hiapi.shopkeeper.entity.activity.Activity;
import cn.hiapi.shopkeeper.entity.activity.ActivityApply;
import cn.hiapi.shopkeeper.entity.order.ActivityOrder;
import cn.hiapi.shopkeeper.enums.ActivityType;
import cn.hiapi.shopkeeper.jpa.activity.ActivityApplyJpa;
import cn.hiapi.shopkeeper.request.CreateOrderRequest;
import cn.hiapi.shopkeeper.service.order.ActivityOrderService;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Map;

/**
 * @author AdinZ
 * @date 2022/12/13 21:19
 */
@Service
public class ActivityApplyService extends AbsActivityService<ActivityApplyJpa, ActivityApply, Long> {
    public ActivityApplyService(DispatchContext dispatchContext) {
        super(dispatchContext);
    }

    @Override
    public ActivityType getActivityType() {
        return ActivityType.APPLY;
    }

    @Override
    public BasicEntity saveExpand(long activityId, JSONObject data) {
        ActivityApply apply = data.toJavaObject(ActivityApply.class);
        if (apply.getApplyNum() <= 0) throw new BasicException("报名人数错误");
        if (StringUtils.isEmpty(apply.getAddress())) {
            throw new BasicException("报名地址错误");
        }
        if (apply.getPrice() != null && apply.getPrice().compareTo(BigDecimal.ZERO) < 0)
            throw new BasicException("报名收费错误");
        if (apply.getApplyFee() == 1) {
            if (apply.getPrice().compareTo(BigDecimal.ZERO) <= 0) throw new BasicException("请输入报名费");
        }else apply.setPrice(BigDecimal.ZERO);
        apply.setAid(activityId);

        return this.save(apply);
    }

    @Override
    @Transactional
    public int deleteByAid(long aid) {
        return ResUtils.getDefault(this.repository.deleteByAid(aid));
    }

    @Override
    @Transactional
    public ActivityOrder createOrder(BasicEntity basic, Activity activity, Map<String, Long> incrementStock, CreateOrderRequest request, Token<Object> token) {
        JSONObject other = request.getOther();
        if (other == null) throw new BasicException("报名联系资料错误");
        String name = other.getString("name");
        String mobile = other.getString("mobile");
        String address = other.getString("address");

        if (StringUtils.isEmpty(name)) {
            throw new BasicException("报名姓名错误");
        }
        if (StringUtils.isEmpty(mobile)) {
            throw new BasicException("报名手机号错误");
        }
        if (StringUtils.isEmpty(address)) {
            throw new BasicException("报名地址错误");
        }


        ActivityApply apply = (ActivityApply) basic;

        if (apply == null) throw new BasicException("报名活动不存在");

        long count = this.dispatchContext.getServiceOne(ActivityOrderService.class).count(
                new QueryWrapper().eq("aid", activity.getId()).eq("buyerId", token.getFid())
                        .eq("statusType", 1).eq("activityType", activity.getType())
        );
        if (count > 0)
            throw new BasicException("您已报过名了");

        final long stockNum = apply.getApplyNum();
        long total = this.dispatchContext.getServiceOne(ProductNumService.class).totalByGid(activity.getId(), AppConst.ACTIVITY_SELL_TOTAL);
        long increment = this.dispatchContext.getServiceOne(RedisService.class).increment(AppConst.ACTIVITY_SELL_STOCK_KEY, activity.getId(), 0L);
        if ((total + increment) >= stockNum) {
            throw new BasicException("报名人数已满");
        }


        this.dispatchContext.getServiceOne(RedisService.class).increment(AppConst.ACTIVITY_SELL_STOCK_KEY, activity.getId(), 1L);
        incrementStock.put(AppConst.ACTIVITY_STOCK_LOCK, activity.getId());
        ActivityOrder order = new ActivityOrder();
        if (request.getSugar() != null)
            order.setSugar(request.getSugar());
        if (apply.getApplyFee() == 1) {
            order.setPrice(apply.getPrice());
        } else apply.setPrice(BigDecimal.ZERO);
        order.setCostPrice(activity.getPrice());
        order.setOtherText(other.toJSONString());

        return order;
    }

    /**
     * @param activity 活动详情
     * @param rate     抵扣比例
     * @param amount   喜糖总量
     * @return
     */
    @Override
    public BigDecimal sugarDeduction(Activity activity, BigDecimal rate, BigDecimal amount, long uid) {
        ActivityApply apply = this.getByAid(activity.getId());
        //最大抵扣系统, 大于余额
        return super.sugarDeduction(apply.getPrice(), rate, amount);
    }
}
